package com.linln.admin.pcs.controller;


import cn.hutool.json.JSONArray;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.linln.admin.config.IDCardEncryptor;
import com.linln.admin.system.service.AppService;
import com.linln.common.data.QuerySpec;
import com.linln.common.utils.*;
import com.linln.common.vo.ResultVo;
import com.linln.component.actionLog.annotation.EntityParam;
import com.linln.component.shiro.ShiroUtil;
import com.linln.modules.system.domain.*;
import com.linln.modules.system.repository.*;
import com.linln.modules.system.service.RoleService;
import com.linln.modules.system.service.UserService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.Predicate;
import java.io.StringWriter;
import java.util.*;


/**
 * 护工基础信息管理
 */
@Controller
@RequestMapping("/pcs/porter")
public class PorterController {

    @Autowired
    private AppService appService;
    @Autowired
    private PorterRepository porterRepository;
    @Autowired
    private PorterConHireLogRepository porterConHireLogRepository;
    @Autowired
    private ThymeleafViewResolver thymeleafViewResolver;
    @Autowired
    private PorterPermissionRepository porterPermissionRepository;
    @Autowired
    private PorterCredentialsRepository porterCredentialsRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private CompanyRepository companyRepository;

    /**
     * 列表页面
     */
    @GetMapping("/index")
    @RequiresPermissions("pcs:porter:index")
    public ResponseEntity<?> index(Model model, @EntityParam Porter porter) {




        return appService.layTable(porterRepository, before -> {

                    // 添加模板变量
                    return model;

                },

                after -> {


                    QuerySpec querySpec = QuerySpec.matching();
                    querySpec.withMatcher("name", QuerySpec.LIKE)
                            .withMatcher("phone", QuerySpec.LIKE)
                            .withMatcher("status", QuerySpec.EQUAL)
                            .withMatcher("sex", QuerySpec.EQUAL);
                    User user = ShiroUtil.getSubject();
                    if (user.getType()!=null&&user.getType().equals("2")) {
                        Long companyId = user.getCompanyId();
                        querySpec.withMatcherValue("companyId", QuerySpec.EQUAL,companyId.toString());
                    }

                    return QuerySpec.of(querySpec);
                    // 添加查询条件
//                    return (Specification<Porter>) (root, query, cb) -> {
//                        Predicate predicate = cb.conjunction();  // 初始条件
//                        //后续根据当前登录账号的角色，查询出当前登录账号的护工信息
//                        Long companyId = porter.getCompanyId();
//                        companyId = 1L;
//                        predicate = cb.and(predicate, cb.equal(root.get("companyId"), companyId));
//                        if (porter.getName() != null) {
//                            predicate = cb.and(predicate, cb.like(root.get("name"), "%"+porter.getName()+"%"));
//                        }
//                        if (porter.getSex() != null) {
//                            predicate = cb.and(predicate, cb.equal(root.get("sex"), porter.getSex()));
//                        }
//                        if (porter.getStatus() != null) {
//                            predicate = cb.and(predicate, cb.equal(root.get("status"), porter.getStatus()));
//                        }
//                        if (porter.getPhone() != null) {
//                            predicate = cb.and(predicate, cb.like(root.get("phone"), "%"+porter.getPhone()+"%"));
//                        }
//
//                        return predicate;
//                    };
                },

                "/pcs/porter/index",

                (pageResult) -> {
                    // 在这里处理 pageResult
                    // 例如：修改每一条数据
                 //   List<Porter> list = (List<Porter>) pageResult.getContent();
                    pageResult.getContent().forEach(item -> {
                        // 对每一项数据进行处理
                        Porter data = (Porter) item;
                        String cardNo = "";
                        try {
                            data.setCardNo(IDCardEncryptor.aesTuoMinDecrypt(data.getCardNo()));
                            data.setPhone(IDCardEncryptor.aesTuoMinPhoneDecrypt(data.getPhone()));
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }

                        Specification specification = (Specification<PorterPermission>) (root, query, cb) -> {
                            Predicate predicate = cb.conjunction();  // 初始条件
                            predicate = cb.and(predicate, cb.equal(root.get("porterId"), data.getId()));
                            predicate = cb.and(predicate, cb.equal(root.get("verifyStatus"), 1));
                            return predicate;
                        };
                        List<PorterPermission> porterPermissions = porterPermissionRepository.findAll(specification);
                        data.setPorterPermissions(porterPermissions);

                        //查询护工证书
                        QuerySpec querySpec = QuerySpec.matching();
                        querySpec.withMatcherValue("porterId", QuerySpec.EQUAL,String.valueOf(data.getId()));
                        List<PorterCredentials> credentialsList = porterCredentialsRepository.findAll(QuerySpec.of(querySpec));
                        if(credentialsList.size()>0){
                            int expireSoonCount = 0; // 即将过期计数器
                            for (PorterCredentials porterCredentials : credentialsList) {
                                // 统计证书到期时间距当前小于30天的
                                if (porterCredentials.getExpireDate() != null) {
                                    long daysBetween = DateUtils.getDaysBetween(new Date(), porterCredentials.getExpireDate());

                                    // 过期或即将在30天内过期
                                    if (daysBetween <= 30) {
                                        expireSoonCount++;
                                    }
                                }
                            }
                            data.setExpireSoonCount(expireSoonCount);
                        }

                    });
                }

        );

    }


    /**
     * 跳转到添加页面

    @RequestMapping("/form")
    @RequiresPermissions("pcs:porter:add")
    public ResponseEntity<?> form(Model model, @EntityParam Porter porter) throws Exception {

        return appService.form(porterRepository, "/pcs/porter/form",
                (isEdit) -> {

                    return model;

                },
                (isEdit, vo) -> {
                    // 在这里处理 vo 变量
                    Porter data = (Porter) vo;
                    //时间格式序列化为yyyy-MM-dd 格式
                    data.setContractEndStr(HelperUtil.dateFormat(data.getContractEnd(),"yyyy-MM-dd"));
                    model.addAttribute("vo", JSONObject.toJSONString(data));
                    // 你可以在这里添加其他逻辑
                    QuerySpec querySpec = QuerySpec.matching();
                    querySpec.withMatcherValue("porterId", QuerySpec.EQUAL,data.getId().toString());
                    List<PorterCredentials> credentials = porterCredentialsRepository.findAll(QuerySpec.of(querySpec));
                    model.addAttribute("credentials", JSONObject.toJSONString(credentials));
                    return model;
                },
                (data) -> {
                    // 保存前数据校验
                    List<ValidationUtil.ValidationRule<?>> rules = new ArrayList<>();
                    // 添加邮箱的校验规则
            //            rules.add(new ValidationUtil.ValidationRule<>(
            //                    porter.getCardNo(),
            //                    email -> email != null ,
            //                    "Email格式不正确"
            //            ));

                    // 执行校验
                    return ValidationUtil.validateFields(rules);

                },
                (data) -> {
                    // 数据处理
                    if(porter.getId() != null){
                        Porter origin = porterRepository.getById(porter.getId());
                       // EntityBeanUtil.copyProperties(origin, porter); // 将beMenu 字段复制到 menu
                        porter.setStatus(origin.getStatus());
                        porter.setCompanyId(origin.getCompanyId());
                        porter.setCompanyName(origin.getCompanyName());
                        porter.setServiceNumber(origin.getServiceNumber());
                        porter.setLeastLimit(origin.getLeastLimit());
                        porter.setIsStatus(origin.getIsStatus());
                        porter.setPassword(origin.getPassword());
                        porter.setScore(origin.getScore());
                    }else{
                        User user = ShiroUtil.getSubject();
                        porter.setCompanyId(user.getCompanyId());
                        porter.setCompanyName(user.getCompanyName());
                        porter.setAge(HelperUtil.getAge(porter.getCardNo()));
                        porter.setStatus((byte) 1);
                        porter.setServiceNumber(0);
                        porter.setLeastLimit(0);
                        porter.setIsStatus((byte) 1);
                        porter.setScore(0);
                    }


                    return porter;
                },

                (data) -> {
                    // 保存后续逻辑在这写
                });
    }

     */


    /**
     * 续聘记录
     */
    @GetMapping("/form")
    @RequiresPermissions("pcs:porter:add")
    public String form(@RequestParam Long id, Model model){
        model.addAttribute("id", id);
        return "/pcs/porter/form";
    }

    /**
     * 护工表单原数据获取
     */
    @GetMapping("/getFormData")
    public ResponseEntity<?>  getFormData(Model model, @RequestParam Long id) throws Exception {
        Porter data = porterRepository.findById(id).get();
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("porterId", QuerySpec.EQUAL, String.valueOf(id));
        List<PorterCredentials> credentials = porterCredentialsRepository.findAll(QuerySpec.of(querySpec));
        Map<String, Object> result = new HashMap<>();
        data.setCardNo(IDCardEncryptor.aesDecrypt(data.getCardNo()));
        data.setPhone(IDCardEncryptor.aesDecrypt(data.getPhone()));
        result.put("porter", data);
        result.put("credentials", credentials);
        return ResponseEntity.ok(ResultVoUtil.success("成功", result));
    }
    @GetMapping("/getCredentials")
    public ResponseEntity<?>  getCredentials(Model model, @RequestParam Long id) throws Exception {
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("porterId", QuerySpec.EQUAL, String.valueOf(id));
        List<PorterCredentials> credentials = porterCredentialsRepository.findAll(QuerySpec.of(querySpec));
        return ResponseEntity.ok(ResultVoUtil.success("成功", credentials));
    }

    @PostMapping("/save")
    @RequiresPermissions("pcs:porter:add")
    public ResponseEntity<?> save(@RequestBody Porter porter) throws Exception {
        List<PorterCredentials> credentials = porter.getCredentials();
        // 数据处理
        if(porter.getId() != null){
            Porter origin = porterRepository.getById(porter.getId());
            // EntityBeanUtil.copyProperties(origin, porter); // 将beMenu 字段复制到 menu
            porter.setStatus(origin.getStatus());
            porter.setCompanyId(origin.getCompanyId());
            porter.setCompanyName(origin.getCompanyName());
            porter.setServiceNumber(origin.getServiceNumber());
            porter.setLeastLimit(origin.getLeastLimit());
            porter.setIsStatus(origin.getIsStatus());
            porter.setPassword(origin.getPassword());
            porter.setScore(origin.getScore());

        }else{
            QuerySpec querySpec = QuerySpec.matching();
            querySpec.withMatcherValue("cardNo", QuerySpec.EQUAL,  IDCardEncryptor.aesEncrypt(porter.getCardNo()));
            List <Porter> porterList = porterRepository.findAll(QuerySpec.of(querySpec));
            if(porterList.size()>0){
                Porter porter1 = porterList.get(0);
                if(porter1.getStatus()==1){
                    return ResponseEntity.ok(ResultVoUtil.error("该身份证号已存在"));
                }else{

                    porter.setId(porter1.getId());
                }

            }


            User user = ShiroUtil.getSubject();
            porter.setCompanyId(user.getCompanyId());
            porter.setCompanyName(user.getCompanyName());
            porter.setStatus((byte) 1);
            porter.setServiceNumber(0);
            porter.setLeastLimit(0);
            porter.setIsStatus((byte) 1);
            porter.setScore(0);
        }
        Company company = companyRepository.findById(porter.getCompanyId()).get();
        porter.setIsWl(company.getIsWl());
        porter.setAge(HelperUtil.getAge(porter.getCardNo()));
        porter.setCardNo(IDCardEncryptor.aesEncrypt(porter.getCardNo()));
        porter.setPhone(IDCardEncryptor.aesEncrypt(porter.getPhone()));
        porterRepository.save(porter);
        for (PorterCredentials porterCredentials : credentials) {
            if (porterCredentials.getId() != null) {
                PorterCredentials porterCredentials1 = porterCredentialsRepository.findById(porterCredentials.getId()).get();
                porterCredentials1.setStatus((byte) 3);
                porterCredentialsRepository.save(porterCredentials1);
            }
            porterCredentials.setPorterId(porter.getId());
            porterCredentialsRepository.save(porterCredentials);
        }
        return ResponseEntity.ok(ResultVoUtil.success("成功"));
    }





    /**
     * 人员续聘
     */
    @RequestMapping("/hire")
    @RequiresPermissions("pcs:porter:hire")
    public ResponseEntity<?> hire(Model model, @EntityParam PorterConHireLog porterConHireLog) throws Exception {

        String method = HttpServletUtil.getMethod();
        if (method.equals("GET")) {
            String id = HttpServletUtil.getParameter("id");
            Porter data = porterRepository.getById(Long.parseLong(id));
            data.setAge(HelperUtil.getAge(data.getCardNo()));
            data.setContractEndStr(HelperUtil.dateFormat(data.getContractEnd(),"yyyy-MM-dd"));
            model.addAttribute("vo", data);
            Context context = new Context();
            // 将数据加入到 Thymeleaf 上下文中
            context.setVariables(model.asMap());
            // 使用 Thymeleaf 渲染模板
            StringWriter writer = new StringWriter();
            thymeleafViewResolver.getTemplateEngine().process("/pcs/porter/hire_form", context, writer);
            return ResponseEntity.ok(writer.toString());
        }else{
            if(porterConHireLog.getPorterId() != null){
                Porter origin = porterRepository.getById(porterConHireLog.getPorterId());
                Integer years = porterConHireLog.getYears();
                // 使用 Calendar 处理日期加减
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(origin.getContractEnd());
                calendar.add(Calendar.YEAR, years);
                // 更新合同结束日期
                origin.setContractEnd(calendar.getTime());
                origin.setStatus((byte) 1);
                porterConHireLog.setContractEnd(calendar.getTime());
                porterRepository.save(origin);
                porterConHireLogRepository.save(porterConHireLog);

            }

            return ResponseEntity.ok(ResultVoUtil.success("成功"));
        }

    }

    /**
     * 续聘记录
     */
    @GetMapping("/hire/log")
    @RequiresPermissions("pcs:porter:hire:log")
    public String hireLog(@RequestParam Long id, Model model){
        Porter data = porterRepository.getById(id);
        data.setAge(HelperUtil.getAge(data.getCardNo()));
        data.setContractEndStr(HelperUtil.dateFormat(data.getContractEnd(),"yyyy-MM-dd"));
        model.addAttribute("vo", data);
        Specification specification = (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(criteriaBuilder.equal(root.get("porterId"), id));
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        List<PorterConHireLog> log = porterConHireLogRepository.findAll(specification);
        log.forEach(item -> {
            item.setContractEndStr(HelperUtil.dateFormat(item.getContractEnd(),"yyyy-MM-dd"));
        });
        model.addAttribute("log", log);

        return "/pcs/porter/hire_log";
    }






    /**
     * 修改状态
     * @param model
     * @param porter
     * @return
     * @throws Exception
     */
    @RequestMapping("/state")
    @RequiresPermissions("pcs:porter:state")
    public ResponseEntity<?> state(Model model, @EntityParam Porter porter) throws Exception {

        return appService.save(porterRepository, (data) -> {
            List<ValidationUtil.ValidationRule<?>> rules = new ArrayList<>();
            if(porter.getStatus()==0){
                //查询是否有服务中的订单
                QuerySpec querySpec = QuerySpec.matching();
                List<Object> orderStatus = new ArrayList<>();
                orderStatus.add(2);
                orderStatus.add(1);
                orderStatus.add(3);
                orderStatus.add(4);
                querySpec.withMatcherIn("orderStatus", orderStatus)
                        .withMatcherValue("porterId", QuerySpec.EQUAL, String.valueOf(porter.getId()));
                if(orderRepository.count(QuerySpec.of(querySpec))>0){
                    rules.add(new ValidationUtil.ValidationRule<>(
                            "sn",
                            Objects::isNull,
                            "该护工存在服务中订单,禁止操作!!!"
                    ));
                }
            }
            // 校验数据
            return ValidationUtil.validateFields(rules);

        }, (data) -> {
            // 处理数据
            Porter origin = porterRepository.getById(porter.getId());
            origin.setStatus(porter.getStatus());
            return origin;

        }, (data) -> {
            // 更新后操作
            if(porter.getStatus()==3 || porter.getStatus()==0){
                QuerySpec querySpec = QuerySpec.matching();
                querySpec.withMatcherValue("porterId", QuerySpec.EQUAL, String.valueOf(porter.getId()));
                porterPermissionRepository.deleteAll(porterPermissionRepository.findAll(QuerySpec.of(querySpec)));
            }
        });

    }


    /**
     * 密码
     */
    @RequestMapping("/pwd")
    @RequiresPermissions("pcs:porter:pwd")
    public ResponseEntity<?> pwd(Model model,
                                 @RequestParam(value = "id") Porter porter,
                                 @RequestParam(required = false) String password,
                                 @RequestParam(required = false) String confirm) throws Exception {

        return appService.form(porterRepository, "/pcs/porter/pwd", (isEdit) -> {

                    return model;

                }, (data) -> {

                    // 保存前数据校验
                    List<ValidationUtil.ValidationRule<?>> rules = new ArrayList<>();

                    rules.add(new ValidationUtil.ValidationRule<>(
                            password,
                            passwordPram -> passwordPram != null && !passwordPram.isEmpty(),
                            "请输入密码"
                    ));

                    rules.add(new ValidationUtil.ValidationRule<>(
                            confirm,
                            confirmPram -> confirmPram != null && !confirmPram.isEmpty(),
                            "请再次输入密码"
                    ));
                    rules.add(new ValidationUtil.ValidationRule<>(
                            password,
                            pwd -> pwd != null && pwd.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[\\W_]).+$"),
                            "密码必须包含大小写字母、数字和特殊符号"
                    ));

                    rules.add(new ValidationUtil.ValidationRule<>(
                            password,
                            passwordPram -> Objects.equals(passwordPram, confirm),
                            "两次密码输入不一致"
                    ));

                    // 执行校验
                    return ValidationUtil.validateFields(rules);

                }, (data) -> {

                    // 数据处理
                    String salt = "qfB6mY";
                    String encrypt = ShiroUtil.encrypt(password, salt);
                    porter.setPassword(encrypt);

                    return porter;

                },

                (data) -> {
                    // 保存后续逻辑在这写
                });
    }

    @RequestMapping("/detail")
    @RequiresPermissions("pcs:porter:detail")
    public String detail(Model model, @EntityParam Porter porter) throws Exception{
        Porter data = porterRepository.getById(porter.getId());
        //data.setAge(HelperUtil.getAge(data.getCardNo()));
        data.setContractEndStr(HelperUtil.dateFormat(data.getContractEnd(),"yyyy-MM-dd"));
        data.setCardNo(IDCardEncryptor.aesTuoMinDecrypt(data.getCardNo()));
        data.setPhone(IDCardEncryptor.aesTuoMinPhoneDecrypt(data.getPhone()));
        model.addAttribute("vo", data);
        QuerySpec querySpec = QuerySpec.matching().withMatcherValue("porterId", QuerySpec.EQUAL, String.valueOf(porter.getId()));
        List<PorterCredentials> porterCredentials = porterCredentialsRepository.findAll(QuerySpec.of(querySpec));
        for (PorterCredentials porterCredential : porterCredentials) {
            porterCredential.setExpireDateStr(HelperUtil.dateFormat(porterCredential.getExpireDate(),"yyyy-MM-dd"));

            // 统计证书到期时间距当前小于30天的
            if (porterCredential.getExpireDate() != null) {
                long daysBetween = DateUtils.getDaysBetween(new Date(), porterCredential.getExpireDate());

                // 过期或即将在30天内过期
                if (daysBetween <= 30) {
                    porterCredential.setIsExpire(1);
                }
            }
        }
        model.addAttribute("credentials", porterCredentials);
        return "/pcs/porter/detail";
    }



}
